#include <opencv4/opencv2/opencv.hpp>
#include "acl/acl.h"
#include <time.h>

using namespace cv;
using namespace std;



int main()
{
    // ***************************** 初始准备工作 *****************************
    aclInit("");        // 初始化
    aclrtSetDevice(0);  // 设置使用第1块NPU

    // 加载模型
    uint32_t modelId;
    aclError ret = aclmdlLoadFromFile("./model/temp.om", &modelId);



    // ***************************** 准备模型输入 *****************************
    // 创建输入链表
    aclmdlDataset * inputDataset = aclmdlCreateDataset();

    // 创建第1个输入
    float * cpu_input1_buffer = (float*)malloc(1 * 5 * 4);
    void * npu_input1_buffer;
    int input_data_size = 1 * 5 * 4;
    aclrtMalloc(&npu_input1_buffer, input_data_size, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMemcpy(npu_input1_buffer, input_data_size, cpu_input1_buffer, input_data_size, ACL_MEMCPY_DEVICE_TO_DEVICE);
    aclDataBuffer * inputData1 = aclCreateDataBuffer(npu_input1_buffer, input_data_size);   // 将第1个输入绑定到结构体上
    aclmdlAddDatasetBuffer(inputDataset, inputData1);   // 将结构体放到链表上

    // 创建第2个输入
    float * cpu_input2_buffer = (float*)malloc(1 * 5 * 4);
    void * npu_input2_buffer;
    input_data_size = 1 * 5 * 4;
    aclrtMalloc(&npu_input2_buffer, input_data_size, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMemcpy(npu_input2_buffer, input_data_size, cpu_input2_buffer, input_data_size, ACL_MEMCPY_DEVICE_TO_DEVICE);
    aclDataBuffer * inputData2 = aclCreateDataBuffer(npu_input2_buffer, input_data_size);   // 将第2个输入绑定到结构体上
    aclmdlAddDatasetBuffer(inputDataset, inputData2);   // 将结构体放到链表上



    // ***************************** 准备模型输出空间 *****************************
    aclmdlDataset * outputDataset = aclmdlCreateDataset();

    void * npu_output_buffer;
    int output_data_size = 1 * 1 * 4;
    aclrtMalloc(&npu_output_buffer, output_data_size, ACL_MEM_MALLOC_HUGE_FIRST);
    aclDataBuffer * outputData = aclCreateDataBuffer(npu_output_buffer, output_data_size);
    aclmdlAddDatasetBuffer(outputDataset, outputData);



    // ***************************** 模型执行推理 *****************************
    ret = aclmdlExecute(modelId, inputDataset, outputDataset);

    

    // ***************************** 模型输出后处理 *****************************
    float * out_class_data = (float*)malloc(output_data_size);
    aclrtMemcpy((void*)out_class_data, output_data_size, npu_output_buffer, output_data_size, ACL_MEMCPY_DEVICE_TO_DEVICE);
    printf("%f\n", out_class_data[0]);



    // ***************************** 释放昇腾资源 *****************************
    aclrtFree(npu_input1_buffer);
    aclrtFree(npu_input2_buffer);
    aclmdlDestroyDataset(inputDataset);
    aclrtFree(npu_output_buffer);
    aclmdlDestroyDataset(outputDataset);
    aclmdlUnload(modelId);
    aclrtResetDevice(0);
    aclFinalize();

    return 0;
}

